///////////////////////////////////////////////////////////////////
// ENBSeries effect file
// made by : PetkaGTA, Marty McFly
// Feel free to mod it like you want & distribute on your own settings
// As long as you mention everyone's names
// 
//Copyright : Boris Vorontsov/PetkaGTA/Marty McFly
//
//////////////////////////////////////////////////////////////////

//SAGE(San Andreas Graphics Enhancement)
//Advanced Color Correction, Bloom and Tonemapping in 1 shader(!!)

//--------------------------------------------------------------------------------------
// Defines
//--------------------------------------------------------------------------------------
//#define TONEMAPPING_MODE_0
//#define TONEMAPPING_MODE_1
//#define TONEMAPPING_MODE_2
//#define TONEMAPPING_MODE_3
//#define TONEMAPPING_MODE_4
//#define TONEMAPPING_MODE_5//not recomended
//--------------------------------------------------------------------------------------
// Vectors, floats and etc.
//--------------------------------------------------------------------------------------

float ScreenScaleY;
float ScreenSize;
float2 screenRes = {1024,768};//  

float _ExposureAdjustment = 3.0;//Adjust Exposure;  
static const float gray = 0.333;
static const float white = 1.0;
float4 _HdrParams = {gray,gray,gray,white*white};

static const float thresh = 0.23;//        (       -    )
float4 threshhold = {thresh, 1/(1-thresh), 5.0, 5.0};
float BloomIntensity = 0.5;//  

//--------------------------------------------------------------------------------------
// Textures
//--------------------------------------------------------------------------------------

texture2D texColor;
texture2D texDepth;
texture2D texNoise;

//--------------------------------------------------------------------------------------
// Sampler Inputs
//--------------------------------------------------------------------------------------

sampler2D InputSampler = sampler_state
{
    Texture = (texColor);
    MinFilter = POINT;
    MagFilter = POINT;
    MipFilter = POINT;
    AddressU   = Clamp;
	AddressV   = Clamp;
	SRGBTexture=FALSE;
	MaxMipLevel=0;
	MipMapLodBias=0;
};

sampler2D SamplerDepth = sampler_state
{
	Texture   = <texDepth>;
	MinFilter = POINT;
	MagFilter = POINT;
	MipFilter = NONE;
	AddressU  = Clamp;
	AddressV  = Clamp;
	SRGBTexture=FALSE;
	MaxMipLevel=0;
	MipMapLodBias=0;
};

sampler2D SamplerNoise = sampler_state
{
	Texture   = <texNoise>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	AddressU  = Wrap;
	AddressV  = Wrap;
	SRGBTexture = FALSE;
	MaxMipLevel = 0;
	MipMapLodBias = 0;
};

struct VS_OUTPUT_POST
{
	float4 vpos  : POSITION;
	float2 txcoord : TEXCOORD0;
};

struct VS_INPUT_POST
{
	float3 pos  : POSITION;
	float2 txcoord : TEXCOORD0;
};

//--------------------------------------------------------------------------------------
// Functions
//--------------------------------------------------------------------------------------

float Luminance( float3 c )
{
	return dot( c, float3(0.22, 0.707, 0.071) );
}

//--------------------------------------------------------------------------------------
// Vertex Shader Input
//--------------------------------------------------------------------------------------

VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
	VS_OUTPUT_POST OUT;

	float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);

	OUT.vpos=pos;
	OUT.txcoord.xy=IN.txcoord.xy;

	return OUT;
}

float4 paramsS = {1.0,1.0,1.0,1.0};// 
float4 paramsM = {1.0,1.0,1.0,1.0};// ( )
float4 paramsH = {1.0,1.0,1.0,1.0};//  
float _Saturation = 1.6;//
const float blurSize = 1.0/256.0;//1/   (32,128,512,1024)
const float BlurDownsampling = 8;// (   16(   8  ))

float4 CCShadow (VS_OUTPUT_POST i, float2 vPos : VPOS) : COLOR
{
	float4 col = tex2D(InputSampler, i.txcoord);
	//float4 color = tex2Dlod(InputSampler, float4(i.txcoord,0,8));
	
    float4 sum = float4(0,0,0,0);
 
    // blur this in y (vertical)
    // also I downsample it to get interesting result 


																			#include "SweetFX\Shaders\ProcessSum.h"
	
	// do some cool stuff to get bloom...
	float4 color = max(float4(0.0,0.0,0.0,0.0), sum-threshhold.x);
	float4 toBlend = saturate (color * BloomIntensity);
	
	
	
	float4 smpl = 1-(1-col)*(1-toBlend);
	
	float factor = max(smpl.x, max(smpl.y, smpl.z));
	float factorM = (smpl.x + smpl.y + smpl.z)/3;
	float4 shadows = paramsS;
	float4 midtones = paramsM;
	float4 highlights = paramsH;
	
	float4 Color;
	
	if(factor < 0.1)	//Shadows
	{
		if(factor > 0.01)
		{
			factor = (factor + 0.09)*10;
			
			shadows.w = shadows.x; //.w is value backup
			shadows.x = ((1 - shadows.w) / 2) * factor;
			shadows.x += shadows.w;	//Adding backup
			
			shadows.w = shadows.y; //.w is value backup
			shadows.y = ((1 - shadows.w) / 2) * factor;
			shadows.y += shadows.w;	//Adding backup
			
			shadows.w = shadows.z; //.w is value backup
			shadows.z = ((1 - shadows.w) / 2) * factor;
			shadows.z += shadows.w;	//Adding backup
		}
		Color = float4(smpl.x * shadows.x, smpl.y * shadows.y, smpl.z * shadows.z, smpl.w);	
	}
	else if(factorM >= 0.1 && factorM <= 0.5)	//Middle-tones
	{
		if(factorM > 0.3)
		{
			factorM = (factorM - 0.31)*10;
			
			midtones.w = midtones.x; //.w is value backup
			midtones.x = ((1 - midtones.w) / 2) * factorM;
			midtones.x += midtones.w;	//Adding backup
			
			midtones.w = midtones.y; //.w is value backup
			midtones.y = ((1 - midtones.w) / 2) * factorM;
			midtones.y += midtones.w;	//Adding backup
			
			midtones.w = midtones.z; //.w is value backup
			midtones.z = ((1 - midtones.w) / 2) * factorM;
			midtones.z += midtones.w;	//Adding backup
		}
		else if(factorM <= 0.3)
		{
			factorM = (factorM - 0.1)*10;
			
			midtones.w = midtones.x;
			midtones.x = (1 - midtones.w) - (factorM * ((1 - midtones.w) / 2));
			midtones.x += midtones.w;
			
			midtones.w = midtones.y;
			midtones.y = (1 - midtones.w) - (factorM * ((1 - midtones.w) / 2));
			midtones.y += midtones.w;
			
			midtones.w = midtones.z;
			midtones.z = (1 - midtones.w) - (factorM * ((1 - midtones.w) / 2));
			midtones.z += midtones.w;
		}
		
		Color = float4(smpl.x * midtones.x, smpl.y * midtones.y, smpl.z * midtones.z, smpl.w);
	}		
	else if(factorM > 0.5)	//Hightlights
	{
		if(factorM <= 0.8)
		{
			factorM = (factorM - 0.51)*10;
			
			highlights.w = highlights.x;
			highlights.x = (1 - highlights.w) - (factorM * ((1 - highlights.w) / 2));
			highlights.x += highlights.w;
			
			highlights.w = highlights.y;
			highlights.y = (1 - highlights.w) - (factorM * ((1 - highlights.w) / 2));
			highlights.y += highlights.w;
			
			highlights.w = highlights.z;
			highlights.z = (1 - highlights.w) - (factorM * ((1 - highlights.w) / 2));
			highlights.z += highlights.w;
		}
	
		Color = float4(smpl.x * highlights.x, smpl.y * highlights.y, smpl.z * highlights.z, smpl.w);
	}
	else Color = smpl;
	
	float lum = Luminance(Color.xyz);
return Color;
	#ifdef TONEMAPPING_MODE_0
	Color = float4(lerp(float3(lum,lum,lum), Color.xyz, _Saturation),1);
	return 1-exp2(-_ExposureAdjustment * Color);
	#endif
	#ifdef TONEMAPPING_MODE_1
	float avgLum = tex2Dlod(InputSampler, float4(IN.txcoord,0,10));
	
	float cieLum = max(0.000001, Luminance(Color.rgb)); //ToCIE(Color.rgb);
	
	float lumScaled = cieLum * _HdrParams.z / (0.001 + avgLum);
	
	lumScaled = (lumScaled * (1.0f + lumScaled / (_HdrParams.w)))/(1.0f + lumScaled);
	
	//cie.r = lumScaled; 
	
	Color.rgb = Color.rgb * (lumScaled / cieLum);
	
	//color.rgb = FromCIE(cie);		
	return Color;
	#endif
	#ifdef TONEMAPPING_MODE_2
	float A = 0.15;
	float B = 0.50;
	float C = 0.10;
	float D = 0.20;
	float E = 0.02;
	float F = 0.30;
	float W = 11.2;

	Color *= _ExposureAdjustment;

	float ExposureBias = 2.0;
	float3 x = ExposureBias*Color;
	float3 curr = ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
	
	x = W;
	float3 whiteScale = 1.0f/(((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F);
	float3 clr = curr*whiteScale;

	// float3 retColor = pow(clr,1/2.2); // we have SRGB write enabled at this stage

	return float4(clr, 1.0);
	#endif
	#ifdef TONEMAPPING_MODE_3
	float lum = Luminance(Color.rgb); 
	float lumTm = lum * _ExposureAdjustment;
	float scale = lumTm / (1+lumTm);  
	return float4(Color.rgb * scale / lum, Color.a);
	#endif
	#ifdef TONEMAPPING_MODE_4
	Color *= _ExposureAdjustment;
	float4 X = max(float4(0.0,0.0,0.0,0.0), Color-0.004);
	float4 retColor = (X*(6.2*X+.5))/(X*(6.2*X+1.7)+0.06);
	return retColor*retColor;
	#endif
	#ifdef TONEMAPPING_MODE_5
	float4 tapA = tex2Dlod(InputSampler, float4(i.txcoord + screenRes * 0.5,0,10));
	float4 tapB = tex2Dlod(InputSampler, float4(i.txcoord - screenRes * 0.5,0,10));
	float4 tapC = tex2Dlod(InputSampler, float4(i.txcoord + screenRes * float2(0.5,-0.5),0,10));
	float4 tapD = tex2Dlod(InputSampler, float4(i.txcoord - screenRes * float2(0.5,-0.5),0,10));
		
	float4 average = (tapA+tapB+tapC+tapD)/4;
	average.y = max(max(tapA.y,tapB.y), max(tapC.y,tapD.y));
	float2 avgLum = average;
	
	float cieLum = max(0.000001, Luminance(Color.rgb)); //ToCIE(color.rgb);
	
	float lumScaled = cieLum * _HdrParams.z / (0.001 + avgLum.x);
	
	lumScaled = (lumScaled * (1.0f + lumScaled / (avgLum.y*avgLum.y)))/(1.0f + lumScaled);
	
	//cie.r = lumScaled; 
	
	Color.rgb = Color.rgb * (lumScaled / cieLum);
	
	//color.rgb = FromCIE(cie);
	return Color;
	#endif
}
//--------------------------------------------------------------------------------------
// Compiler 1
//--------------------------------------------------------------------------------------

technique PostProcess
{	
	pass P0
	{
		VertexShader = compile vs_3_0 VS_PostProcess();
		PixelShader  = compile ps_3_0 CCShadow();
	}
}